package com.fyt.reachgo.service.impl;


import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fyt.reachgo.Repository.TravelGuideRepository;
import com.fyt.reachgo.Repository.TravelRequestRepository;
import com.fyt.reachgo.domain.Result;
import com.fyt.reachgo.domain.TravelGuide;
import com.fyt.reachgo.domain.TravelRequest;
import com.fyt.reachgo.domain.TravelRoute;
import com.fyt.reachgo.domain.dto.UserDTO;
import com.fyt.reachgo.mapper.TravelRequestMapper;
import com.fyt.reachgo.mapper.TravelRouteMapper;
import com.fyt.reachgo.utils.UserHolder;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static com.fyt.reachgo.config.RabbitMQConfig.TRAVEL_REQUEST_USER_EXCHANGE;
import static com.fyt.reachgo.config.RabbitMQConfig.TRAVEL_REQUEST_USER_ROUTING_KEY;

@Service
public class OaService {

    final ChatClient aiClient;

    @Autowired
    private TravelGuideRepository travelGuideRepository;

    @Autowired
    private TravelRequestRepository travelRequestRepository;

    @Autowired
    private TravelRouteMapper travelRouteMapper;

    @Autowired
    private TravelRequestMapper travelRequestMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public OaService(ChatClient aiClient) {
        this.aiClient = aiClient;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW) // 修改事务传播行为
    public Result generateRoute(TravelRequest travelRequest) {

        try {
            // 查询历史路书
            List<TravelGuide> similarGuides = travelGuideRepository
                    .findByDestinationAndDays(travelRequest.getDestination(), travelRequest.getDays());

            // 构建 AI 提示词
            String aiPrompt = buildAIPrompt(travelRequest, similarGuides);
            System.out.println("AI Prompt: " + aiPrompt);

            // 调用 AI 服务
            String aiResponse = aiClient.prompt()
                    .user(aiPrompt) // 设置用户输入
                    .call() // 发送请求
                    .content(); // 获取响应内容
            System.out.println("AI Response: " + aiResponse);

            // 解析 AI 响应
            TravelRoute route = parseAIResponse(travelRequest, aiResponse);
            System.out.println("Return Parsed Route: " + route);

            // 更新请求状态
            travelRequest.setStatus("completed");
            // 主键检查
            if (travelRequest.getId() == null) {
                throw new IllegalStateException("TravelRequest ID未生成");
            }

            travelRequestMapper.insert(travelRequest);
            travelRouteMapper.insert(route);
//            travelRequestRepository.save(travelRequest);
            // 获取用户信息
            UserDTO user = UserHolder.getUser();
            rabbitTemplate.convertAndSend(TRAVEL_REQUEST_USER_EXCHANGE, TRAVEL_REQUEST_USER_ROUTING_KEY, user.getUserId());
            // 返回成功结果
            return Result.success(route);
        } catch (Exception e) {
            // 异常处理：记录日志并返回基础路线
            System.err.println("生成路线失败: " + e.getMessage());
            e.printStackTrace();

            // 返回基础路线作为降级方案
            TravelRoute basicRoute = generateBasicRoute(travelRequest);
            return Result.success(basicRoute);
        }
    }

    private String buildAIPrompt(TravelRequest request, List<TravelGuide> similarGuides) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("你是一名专业旅行规划师。请根据以下需求创建行程，并严格按以下要求返回结果：\n")
                .append("1. 仅返回 JSON 格式数据，不要包含任何其他文本或注释\n")
                .append("2. 数据结构必须完全匹配示例格式\n")
                .append("3. 必须包含以下字段：\n")
                .append("   - 出发地和目的地的名称及经纬度\n")
                .append("   - 每日行程中每个景点的具体时间、名称、经纬度，所有经纬度必须基于百度地图（BD-09坐标系），保证所有经纬度真实可靠\n")
                .append("   - 每日住宿的酒店名称及经纬度\n")
                .append("   - 所有经纬度必须基于百度地图（BD-09坐标系），保证所有经纬度真实可靠\n")
                .append("   - 每日早餐、午餐、晚餐的详细推荐\n")
                .append("需求详情：\n")
                .append("- 出发地：").append(request.getDeparture()).append("\n")
                .append("- 目的地：").append(request.getDestination()).append("\n")
                .append("- 行程天数：").append(request.getDays()).append("\n")
                .append("- 出行人数：").append(request.getPeopleCount()).append("\n")
                .append("- 偏好交通：").append(request.getTransportation()).append("\n")
                .append("参考格式：\n")
                .append("""
                  {
                    "departure": {
                      "name": "上海",
                      "latitude": 31.230416,
                      "longitude": 121.473701
                    },
                    "destination": {
                      "name": "北京",
                      "latitude": 39.904202,
                      "longitude": 116.407394
                    },
                    "days": [
                      {
                        "day": 1,
                        "schedule": [
                          {
                            "type": "景点",
                            "name": "天安门广场",
                            "startTime": "08:00",
                            "endTime": "10:00",
                            "latitude": 39.909545,
                            "longitude": 116.404000
                          },
                          {
                            "type": "景点",
                            "name": "故宫",
                            "startTime": "10:30",
                            "endTime": "15:00",
                            "latitude": 39.916344,  // 百度地图精确坐标
                            "longitude": 116.397156
                          }
                        ],
                        "accommodation": {
                          "hotelName": "北京王府井希尔顿酒店",
                          "latitude": 39.913818,  // 百度地图坐标
                          "longitude": 116.413384
                        },
                        "meals": {
                          "breakfast": "酒店自助早餐（含老北京豆汁）",
                          "lunch": "全聚德烤鸭店（王府井店）",
                          "dinner": "四季民福故宫店"
                        }
                      }
                    ]
                  }
                  """);

//        System.out.println("question: " + prompt);
        return prompt.toString();
    }

    private TravelRoute parseAIResponse(TravelRequest request, String aiResponse) {
        try {
            System.out.println("Raw AI Response: " + aiResponse);

            // 预处理：移除 JSON 代码块标记和其他非 JSON 内容
            String cleanedResponse = aiResponse
                    .replaceAll("```json", "")  // 移除开头的 ```json
                    .replaceAll("```", "")       // 移除结尾的 ```
                    .replaceAll("//.*|/\\*.*?\\*/", "")
                    .trim();                     // 去除首尾空格

            System.out.println("Cleaned Response: " + cleanedResponse);

            // 检查是否是 JSON 格式
            if (!cleanedResponse.startsWith("{")) {
                throw new RuntimeException("AI响应不是有效的JSON格式");
            }

            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(cleanedResponse);
            System.out.println("Parsed JSON: " + root);

            TravelRoute route = new TravelRoute();
            route.setGeneratedTime(LocalDateTime.now());
            route.setRequestId(request.getId());


            route.setRouteData(root);
            System.out.println("Parsed return Route: " + route);
            return route;
        } catch (Exception e) {
            throw new RuntimeException("AI响应解析失败", e);
        }
    }

    private TravelRoute generateBasicRoute(TravelRequest request) {
        TravelRoute route = new TravelRoute();
        route.setGeneratedTime(LocalDateTime.now());
        route.setRequestId(request.getId());
        route.setRouteData(List.of(
                "出发地：" + request.getDeparture(),
                "目的地：" + request.getDestination(),
                "示例路线：" + request.getDeparture() + " -> " + request.getDestination()
        ));
        return route;
    }
}
